/**
 *====================================================
 * 文件名称: FinanceBulkstockServiceImpl.java
 * 修订记录：
 * No    日期				作者(操作:具体内容)
 * 1.    2015年09月23日	chenxy(创建:创建文件)
 *====================================================
 * 类描述：(说明未实现或其它不应生成javadoc的内容)
 */
package com.yuexunit.finance.project.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.yuexunit.finance.common.util.BeanUtils;
import com.yuexunit.finance.project.entity.ContainerBulkstockEntity;
import com.yuexunit.finance.project.entity.ContainerInventoryEntity;
import com.yuexunit.finance.project.entity.FinanceBulkstockEntity;
import com.yuexunit.finance.project.entity.lexicon.SupervisionStateEnum;
import com.yuexunit.inject.annotation.Implements;
import com.yuexunit.page.PageCriteria;
import com.yuexunit.page.PageList;
import com.yuexunit.persist.PersistUtil;
import com.yuexunit.persist.annotation.Transactional;

/**
 * @ClassName: FinanceBulkstockServiceImpl
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @author chenxy
 * @date 2015年09月23日 18:56:17
 */
@Implements(FinanceBulkstockService.class)
public class FinanceBulkstockServiceImpl implements FinanceBulkstockService {

	@Override
	public void createFinanceBulkstockEntity(FinanceBulkstockEntity entity) {
		if (entity.getFinancePrice() == null) {
			entity.setFinancePrice(BigDecimal.ZERO);
		}
		if (entity.getRecieve() == null) {
			entity.setRecieve(BigDecimal.ZERO);
		}
		if (entity.getSupervision() == null) {
			entity.setSupervision(BigDecimal.ZERO);
		}
		if (entity.getIncustody() == null) {
			entity.setIncustody(BigDecimal.ZERO);
		}
		entity.setHarbor(BigDecimal.ZERO);
		entity.setPickup(BigDecimal.ZERO);
		entity.setAbnormal(BigDecimal.ZERO);
		PersistUtil.insert(entity);
	}

	@Override
	public void updateFinanceBulkstockEntity(FinanceBulkstockEntity entity) {
		FinanceBulkstockEntity persist = PersistUtil.get(FinanceBulkstockEntity.class, entity.getBulkstockId());
		BeanUtils.copyProperties(entity, persist);
		PersistUtil.update(persist);
	}

	@Override
	@Transactional
	public void renovateFinanceBulkstock(FinanceBulkstockEntity persist) {
		PersistUtil.update(persist);
	}

	@Override
	public void deleteFinanceBulkstockEntity(Long bulkstockId) {
		PersistUtil.delete(FinanceBulkstockEntity.class, bulkstockId);
	}

	@Override
	public FinanceBulkstockEntity inquireFinanceBulkstock(Long bulkstockId) {
		return PersistUtil.get(FinanceBulkstockEntity.class, bulkstockId);
	}

	@Override
	public List<FinanceBulkstockEntity> inquireFinanceBulkstockList(Long financeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		return PersistUtil.get(criteria);
	}

	@Override
	public PageList<FinanceBulkstockEntity> inquireFinanceBulkstockPageList(Long financeId, String keyword, PageCriteria page) {
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
		if (StringUtils.isNotBlank(keyword)) {
			criteria.add(Restrictions.like("bulkstockName", "%" + keyword + "%"));
		}
		if (financeId != null) {
			criteria.add(Restrictions.eq("financeId", financeId));
		}
		PageList<FinanceBulkstockEntity> financeBulkstockList = PersistUtil.get(criteria, page);
		return financeBulkstockList;
	}
	

	@Override
	public List<FinanceBulkstockEntity> inquireFinanceBulkstockList() {
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
		criteria.addOrder(Order.desc("financeId"));
		return PersistUtil.get(criteria);
	}
	
	@Override
	public List<FinanceBulkstockEntity> inquireProcessingFinanceBulkstockList(Long bulkstockInfoId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
		criteria.add(Restrictions.eq("bulkstockInfoId", bulkstockInfoId));
		criteria.add(Restrictions.gt("supervision", BigDecimal.ZERO));
		return PersistUtil.get(criteria); 
	}

	@Override
	public PageList<FinanceBulkstockEntity> inquirePublicFinanceBulkstockPageList(String bulkstockName, String specification, String originPlace, PageCriteria page) {
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
		if (StringUtils.isNotBlank(bulkstockName)) {
			criteria.add(Restrictions.like("bulkstockName", "%" + bulkstockName + "%"));
		}
		if (StringUtils.isNotBlank(specification)) {
			criteria.add(Restrictions.like("specification", "%" + specification + "%"));
		}
		if (StringUtils.isNotBlank(originPlace)) {
			criteria.add(Restrictions.like("originPlace", "%" + originPlace + "%"));
		}
		criteria.addOrder(Order.desc("bulkstockId"));
		PageList<FinanceBulkstockEntity> bulkstockList = PersistUtil.get(criteria, page);
		return bulkstockList;
	}

	@Override
	public void calculateSupervisionFinanceBulkstock(Long financeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		List<FinanceBulkstockEntity> bulkstockList = PersistUtil.get(criteria);
		Map<Long, FinanceBulkstockEntity> bulkstocks = new HashMap<>();
		Set<Long> bulkstockIds = new HashSet<>();
		for (FinanceBulkstockEntity e : bulkstockList) {
			bulkstocks.put(e.getBulkstockId(), e);
			bulkstockIds.add(e.getBulkstockId());
		}

		criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("abnormal", Boolean.TRUE));
		criteria.add(Restrictions.in("supervisionState", new SupervisionStateEnum[] { SupervisionStateEnum.ALREADY_SUPERVISE, SupervisionStateEnum.RELIEVE_SUPERVISE }));
		criteria.setProjection(Projections.property("inventoryId"));
		List<Long> inventoryIds = PersistUtil.get(criteria);
		List<Object[]> list = new ArrayList<>();
		if (!inventoryIds.isEmpty()) {
			criteria = DetachedCriteria.forClass(ContainerBulkstockEntity.class);
			criteria.add(Restrictions.in("inventoryId", inventoryIds));
			criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("bulkstockId")).add(Projections.sum("quantity")));
			list = PersistUtil.get(criteria);
		}
		for (Object o : list) {
			Object[] m = (Object[]) o;
			FinanceBulkstockEntity bulkstock = bulkstocks.get(Long.parseLong(m[0].toString()));
			if (bulkstock == null) {
				continue;
			}
			System.out.println("wenwenlong++++++++++++++++++++++++++++++++++++++++++++++++" + Long.parseLong(m[0].toString()));
			bulkstock.setSupervision(m[1] == null ? BigDecimal.ZERO : new BigDecimal(m[1].toString()));
			bulkstockIds.remove(Long.parseLong(m[0].toString()));
		}
		for (Long bulkstockId : bulkstockIds) {
			FinanceBulkstockEntity bulkstock = bulkstocks.get(bulkstockId);
			bulkstock.setSupervision(BigDecimal.ZERO);
		}
		for (FinanceBulkstockEntity e : bulkstockList) {
			PersistUtil.update(e);
		}
	}

	@Override
	public void calculateHarborFinanceBulkstock(Long financeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		List<FinanceBulkstockEntity> bulkstockList = PersistUtil.get(criteria);
		Map<Long, FinanceBulkstockEntity> bulkstocks = new HashMap<>();
		for (FinanceBulkstockEntity e : bulkstockList) {
			bulkstocks.put(e.getBulkstockId(), e);
		}
		criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("harborState", Boolean.TRUE));
		criteria.setProjection(Projections.property("inventoryId"));
		List<Long> inventoryIds = PersistUtil.get(criteria);

		criteria = DetachedCriteria.forClass(ContainerBulkstockEntity.class);
		criteria.add(Restrictions.in("inventoryId", inventoryIds));
		criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("bulkstockId")).add(Projections.sum("quantity")));
		List<Object> list = PersistUtil.get(criteria);
		for (Object o : list) {
			Object[] m = (Object[]) o;
			FinanceBulkstockEntity bulkstock = bulkstocks.get(Long.parseLong(m[0].toString()));
			bulkstock.setHarbor(m[1] == null ? BigDecimal.ZERO : new BigDecimal(m[1].toString()));
		}
		for (FinanceBulkstockEntity e : bulkstockList) {
			PersistUtil.update(e);
		}
	}

	@Override
	public void calculatePickupFinanceBulkstock(Long financeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		List<FinanceBulkstockEntity> bulkstockList = PersistUtil.get(criteria);
		Map<Long, FinanceBulkstockEntity> bulkstocks = new HashMap<>();
		for (FinanceBulkstockEntity e : bulkstockList) {
			bulkstocks.put(e.getBulkstockId(), e);
		}
		criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("signState", Boolean.TRUE));
		criteria.setProjection(Projections.property("inventoryId"));
		List<Long> inventoryIds = PersistUtil.get(criteria);

		criteria = DetachedCriteria.forClass(ContainerBulkstockEntity.class);
		criteria.add(Restrictions.in("inventoryId", inventoryIds));
		criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("bulkstockId")).add(Projections.sum("quantity")));
		List<Object> list = PersistUtil.get(criteria);
		for (Object o : list) {
			Object[] m = (Object[]) o;
			FinanceBulkstockEntity bulkstock = bulkstocks.get(Long.parseLong(m[0].toString()));
			bulkstock.setPickup(m[1] == null ? BigDecimal.ZERO : new BigDecimal(m[1].toString()));
		}
		for (FinanceBulkstockEntity e : bulkstockList) {
			PersistUtil.update(e);
		}
	}

	@Override
	public void calculateAbnormalFinanceBulkstock(Long financeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		List<FinanceBulkstockEntity> bulkstockList = PersistUtil.get(criteria);
		Map<Long, FinanceBulkstockEntity> bulkstocks = new HashMap<>();
		Set<Long> bulkstockIds = new HashSet<>();
		for (FinanceBulkstockEntity e : bulkstockList) {
			bulkstocks.put(e.getBulkstockId(), e);
			bulkstockIds.add(e.getBulkstockId());
		}
		criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("abnormal", Boolean.FALSE));
		criteria.setProjection(Projections.property("inventoryId"));
		List<Long> inventoryIds = PersistUtil.get(criteria);
		List<Object[]> list = new ArrayList<>();
		if (!inventoryIds.isEmpty()) {
			criteria = DetachedCriteria.forClass(ContainerBulkstockEntity.class);
			criteria.add(Restrictions.in("inventoryId", inventoryIds));
			criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("bulkstockId")).add(Projections.sum("quantity")));
			list = PersistUtil.get(criteria);
		}
		for (Object o : list) {
			Object[] m = (Object[]) o;
			FinanceBulkstockEntity bulkstock = bulkstocks.get(Long.parseLong(m[0].toString()));
			bulkstock.setAbnormal(m[1] == null ? BigDecimal.ZERO : new BigDecimal(m[1].toString()));
			bulkstockIds.remove(Long.parseLong(m[0].toString()));
		}
		for (Long bulkstockId : bulkstockIds) {
			FinanceBulkstockEntity bulkstock = bulkstocks.get(bulkstockId);
			bulkstock.setAbnormal(BigDecimal.ZERO);
		}
		for (FinanceBulkstockEntity e : bulkstockList) {
			PersistUtil.update(e);
		}
	}

	@Override
	public void calculateIncustodyFinanceBulkstock(Long financeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		List<FinanceBulkstockEntity> bulkstockList = PersistUtil.get(criteria);
		Map<Long, FinanceBulkstockEntity> bulkstocks = new HashMap<>();
		Set<Long> bulkstockIds = new HashSet<>();
		for (FinanceBulkstockEntity e : bulkstockList) {
			bulkstocks.put(e.getBulkstockId(), e);
			bulkstockIds.add(e.getBulkstockId());
		}
		criteria = DetachedCriteria.forClass(ContainerInventoryEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		criteria.add(Restrictions.eq("enabled", Boolean.TRUE));
		criteria.add(Restrictions.eq("abnormal", Boolean.TRUE));
		criteria.add(Restrictions.eq("supervisionState", SupervisionStateEnum.ALREADY_SUPERVISE));
		criteria.setProjection(Projections.property("inventoryId"));
		List<Long> inventoryIds = PersistUtil.get(criteria);
		List<Object[]> list = new ArrayList<>();
		if (!inventoryIds.isEmpty()) {
			criteria = DetachedCriteria.forClass(ContainerBulkstockEntity.class);
			criteria.add(Restrictions.in("inventoryId", inventoryIds));
			criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("bulkstockId")).add(Projections.sum("quantity")));
			list = PersistUtil.get(criteria);
		}
		for (Object o : list) {
			Object[] m = (Object[]) o;
			FinanceBulkstockEntity bulkstock = bulkstocks.get(Long.parseLong(m[0].toString()));
			if (bulkstock == null) {
				continue;
			}
			bulkstock.setIncustody(m[1] == null ? BigDecimal.ZERO : new BigDecimal(m[1].toString()));
			bulkstockIds.remove(Long.parseLong(m[0].toString()));
		}
		for (Long bulkstockId : bulkstockIds) {
			FinanceBulkstockEntity bulkstock = bulkstocks.get(bulkstockId);
			bulkstock.setIncustody(BigDecimal.ZERO);
		}
		for (FinanceBulkstockEntity e : bulkstockList) {
			PersistUtil.update(e);
		}
	}

	@Override
	public Integer[] inquireSupervisionPickupIncustodyFinanceBulkstock(Long financeId) {
		Integer[] quantity = new Integer[4];
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		criteria.setProjection(Projections.projectionList().add(Projections.sum("supervision")).add(Projections.sum("pickup")).add(Projections.sum("abnormal")).add(Projections.sum("incustody")));
		List<Object> list = PersistUtil.get(criteria);
		for (Object o : list) {
			Object[] m = (Object[]) o;
			quantity[0] = Integer.parseInt(m[0].toString());
			quantity[1] = Integer.parseInt(m[1].toString());
			quantity[2] = Integer.parseInt(m[2].toString());
			quantity[3] = Integer.parseInt(m[3].toString());
		}
		return quantity;
	}

	@Override
	public BigDecimal countAbnormalBulkstockQuantity(Long financeId) {
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
		criteria.add(Restrictions.eq("financeId", financeId));
		criteria.setProjection(Projections.projectionList().add(Projections.sum("abnormal")));
		List<Object> list = PersistUtil.get(criteria);
		if (list.isEmpty()) {
			return BigDecimal.ZERO;
		}
		return new BigDecimal(list.get(0).toString());
	}

	@Override
	public List<FinanceBulkstockEntity> inquireFinanceBulkstockList(Long[] bulkstockIds) {
		if (bulkstockIds == null || bulkstockIds.length <= 0) {
			return null;
		}
		DetachedCriteria criteria = DetachedCriteria.forClass(FinanceBulkstockEntity.class);
		criteria.add(Restrictions.in("bulkstockId", bulkstockIds));
		return PersistUtil.get(criteria);
	}
}
